package com.valenx.distributedmulticamerasystem.slice;

import com.valenx.distributedmulticamerasystem.RemoteServiceAbility;
import com.valenx.distributedmulticamerasystem.ResourceTable;
import com.valenx.distributedmulticamerasystem.camera.CameraController;
import com.valenx.distributedmulticamerasystem.camera.api.CodecListener;
import com.valenx.distributedmulticamerasystem.camera.api.OutsideCameraCallBack;
import com.valenx.distributedmulticamerasystem.camera.codec.CodecDecoder;
import com.valenx.distributedmulticamerasystem.camera.codec.CodecEncoder;
import com.valenx.distributedmulticamerasystem.camera.constant.CameraMode;
import com.valenx.distributedmulticamerasystem.camera.constant.CodecConst;

import com.valenx.distributedmulticamerasystem.camera.constant.RemoteCommand;
import com.valenx.distributedmulticamerasystem.camera.view.CameraView;
import com.valenx.distributedmulticamerasystem.utils.*;
import com.valenx.distributedsearch.DistributedSearchAbility;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.agp.graphics.SurfaceOps;
import ohos.agp.utils.Color;
import ohos.ai.asr.AsrClient;
import ohos.ai.asr.AsrIntent;
import ohos.ai.asr.AsrListener;
import ohos.ai.asr.util.AsrResultKey;
import ohos.app.Context;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.bundle.ElementName;
import ohos.data.distributed.common.KvManagerConfig;
import ohos.data.distributed.common.KvManagerFactory;
import ohos.event.commonevent.*;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.audio.AudioCapturer;
import ohos.media.audio.AudioCapturerInfo;
import ohos.media.audio.AudioStreamInfo;
import ohos.media.camera.device.*;
import ohos.media.camera.params.Metadata;
import ohos.media.common.BufferInfo;
import ohos.media.common.Format;
import ohos.media.image.PixelMap;
import ohos.multimodalinput.event.TouchEvent;
import ohos.rpc.*;
import ohos.utils.PacMap;
import ohos.utils.zson.ZSONObject;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static com.valenx.distributedmulticamerasystem.camera.constant.CameraMode.PHOTO_MODE;
import static com.valenx.distributedmulticamerasystem.camera.constant.CameraMode.RECORD_MODE;

public class CameraAbilitySlice extends AbilitySlice implements Component.ClickedListener, RadioContainer.CheckedStateChangedListener, Component.TouchEventListener, OutsideCameraCallBack,CodecListener {
    //日志相关
    static final String TAG = CameraAbilitySlice.class.getSimpleName();
    static final HiLogLabel LOG_LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00102, TAG);

    //组件相关
    private CameraView cameraView;//预览窗口
    private CameraController cameraController;//相机控制器
    private SurfaceProvider pushFlowView1;//推流窗口1
    private SurfaceProvider pushFlowView2;//推流窗口2
    private RadioContainer radioContainer;//单选框容器
    private Text deviceTypeText;//主从机标识文本
    private Image btnAction;//拍照按钮（由于StateElement(Context context, int xmlId)在SDK7之后才支持，故暂时用Image组件和onTouchEvent事件代替相关功能）
    private Image btnThumbnail;//缩略图按钮
    private Image btnSwitch;//切换相机按钮
    private Image btnFlash;//闪光灯按钮
    private Image btnAsr;//语音控制按钮
    private Image btnSplit;//语音控制按钮
    private Image btnSearch;//搜索按钮

    //状态相关
    private boolean isAsrOn;//标记：语音控制是否打开
    private boolean isSplitOn;//标记：分屏预览是否打开
    private boolean isDistributed;//标记：是否为多机位模式
    private boolean isMaster;//标记：是否为主机端

    private String masterDeviceId;//主机端ID
    private ArrayList<String> slaveDeviceIds;//从机端ID
    private String fromDeviceId;//本机设备ID（传出推流数据的设备ID）
    private int slaveNum;//从机数量
    private List<CameraRemoteProxy> cameraRemoteProxys = new ArrayList<>();//主机控制从机的代理列表
    private CameraRemoteProxy MasterRemoteProxy;//从机控制主机的代理
    private FrameConfig photoFrameConfig;//复用拍照专用帧配置
    private MyCommonEventSubscriber subscriber;//订阅者对象
    private CodecEncoder videoEncoder;//从机编码器
    private CodecDecoder videoDecoder1;//主机解码器1
    private CodecDecoder videoDecoder2;//主机解码器2
    private Surface pushFlowSurface1;//分屏监视窗口1
    private Surface pushFlowSurface2;//分屏监视窗口2
    private Format fmt;//编解码器格式

    //ASR相关
    private static AsrClient asrClient;//ASR客户端实例
    private static final Map<String, Boolean> COMMAND_MAP = new HashMap<>();//匹配命令列表
    static {
        COMMAND_MAP.put("开始拍摄", true);
    }
    private boolean isAsrRecord = false;
    private ThreadPoolExecutor poolExecutor;
    private AudioCapturer audioCapturer;
    private boolean recognizeOver; //判断某次识别是否结束

    EventHandler asrHandler = new EventHandler(EventRunner.getMainEventRunner()){
        @Override
        protected void processEvent(InnerEvent event) {
            if(event.eventId == 0){
                getUITaskDispatcher().asyncDispatch(()->{

                    cameraAction();//匹配命令执行拍摄

                    //如果是多机位模式且为主机端，则向从机广播公共事件（远程同步拍摄）
                    if (isDistributed && isMaster) {
                        if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                            try {
                                for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                                    cameraRemoteProxy.remoteControl(RemoteCommand.REMOTE_ACTION.requestCode());
                                }
                            } catch (RemoteException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                });
            }
        }
    };

//===================================================onStart===================================================
//=============================================================================================================

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_camera);
        HiLog.info(LOG_LABEL, "生命周期-onStart()");

        checkDistributed(intent);//①检查当前是否为多机位模式
        connectService();//②连接服务
        initComponent();//③初始化互动组件
    }


//=============================================================================================================

    //①检查当前是否为多机位模式
    private void checkDistributed(Intent intent) {
        //判断是否是多机位模式
        isDistributed = intent.getBooleanParam("DISTRIBUTED_MODE", false);//多机位模式标记
        isMaster = intent.getBooleanParam("IS_MASTER", true);//主机标记

        masterDeviceId = intent.getStringParam("DEVICE_ID_MASTER");//主机ID
        slaveDeviceIds = intent.getStringArrayListParam("DEVICE_ID_SLAVE");//从机ID列表
        slaveNum = intent.getIntParam("SLAVE_NUMBER",0);//从机数量

        //如果是多机位模式
        if (isDistributed) {
            deviceTypeText = findComponentById(ResourceTable.Id_camera_text_ismaster);
            deviceTypeText.setText("连接中");
            //如果是主机
            if (isMaster) {
                HiLog.info(LOG_LABEL, "本设备为✪主机✪");
                for (int i = 0; i < slaveDeviceIds.size(); i++) {
                    HiLog.info(LOG_LABEL, i + "号" + "从机设备ID:" + slaveDeviceIds.get(i));
                }
            }
            //如果是从机
            else {
                fromDeviceId = KvManagerFactory.getInstance().createKvManager(new KvManagerConfig(this)).getLocalDeviceInfo().getId();//本机设备ID（传出推流数据的设备ID）
                HiLog.info(LOG_LABEL, "本设备为○从机○");
                HiLog.info(LOG_LABEL, "主机设备ID:" + masterDeviceId);
            }
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //②连接服务
    private void connectService() {
        if (isDistributed) {
            if (!isMaster) {
                subscribeRemoteEvent(this);//如果是多机位模式且为从机，则订阅远程事件
                connectMasterService(masterDeviceId);//连接主机服务
            } else if (isMaster && !slaveDeviceIds.isEmpty()) {
                subscribeMasterEvent(this);//如果是多机位模式且为主机，则订阅主机要响应的事件
                for (String slaveDeviceId : slaveDeviceIds)
                    connectRemoteService(slaveDeviceId);//如果是多机位模式且为主机，且从机ID非空，则连接远程服务
            }
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //连接远程设备的RemoteServiceAbility
    //主机连接从机服务（广播公共事件）
    private void connectRemoteService(String deviceId) {
        if (!deviceId.isEmpty()) {
            Intent connectPaIntent = new Intent();
            Operation operation = new Intent.OperationBuilder()
                    .withDeviceId(deviceId)
                    .withBundleName(getBundleName())
                    .withAbilityName(RemoteServiceAbility.class.getName())
                    .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                    .build();
            connectPaIntent.setOperation(operation);

            IAbilityConnection conn = new IAbilityConnection() {
                @Override
                public void onAbilityConnectDone(ElementName elementName, IRemoteObject remote, int resultCode) {
                    HiLog.info(LOG_LABEL, "连接从机Service成功......");
                    ToastUtil.showToast(CameraAbilitySlice.this,"连接从机Service成功");
                    cameraRemoteProxys.add(new CameraRemoteProxy(remote));
                    deviceTypeText.setText("✪主机");
                    deviceTypeText.setTextColor(Color.GREEN);
                }

                @Override
                public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
                    HiLog.error(LOG_LABEL, "与从机Service断开连接");
                    ToastUtil.showToast(CameraAbilitySlice.this,"与从机Service断开连接");
                    disconnectAbility(this);
                    deviceTypeText.setTextColor(Color.DKGRAY);
                }
            };

            this.connectAbility(connectPaIntent, conn);
            HiLog.info(LOG_LABEL, "正在连接从机Service......");
            ToastUtil.showToast(CameraAbilitySlice.this,"正在连接从机Service，请稍后");
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //从机连接主机服务（回传已编码数据）
    private void connectMasterService(String deviceId) {
        if (!deviceId.isEmpty()) {
            Intent connectPaIntent = new Intent();
            Operation operation = new Intent.OperationBuilder()
                    .withDeviceId(deviceId)
                    .withBundleName(getBundleName())
                    .withAbilityName(RemoteServiceAbility.class.getName())
                    .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                    .build();
            connectPaIntent.setOperation(operation);

            IAbilityConnection conn = new IAbilityConnection() {
                @Override
                public void onAbilityConnectDone(ElementName elementName, IRemoteObject remote, int resultCode) {
                    HiLog.info(LOG_LABEL, "连接主机Service成功......");
                    ToastUtil.showToast(CameraAbilitySlice.this,"连接主机Service成功");
                    MasterRemoteProxy = new CameraRemoteProxy(remote);
                    deviceTypeText.setText("○从机");
                    deviceTypeText.setTextColor(Color.GREEN);
                }

                @Override
                public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
                    HiLog.error(LOG_LABEL, "与主机Service断开连接");
                    ToastUtil.showToast(CameraAbilitySlice.this,"与主机Service断开连接");
                    disconnectAbility(this);
                    deviceTypeText.setTextColor(Color.DKGRAY);
                }
            };

            this.connectAbility(connectPaIntent, conn);
            HiLog.info(LOG_LABEL, "正在连接主机Service......");
            ToastUtil.showToast(CameraAbilitySlice.this,"正在连接主机Service，请稍后");
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //相机远程代理类
    class CameraRemoteProxy implements IRemoteBroker {
        private static final int ERR_OK = 0;//无错误标识

        private final IRemoteObject cameraRemote;//封装收到的代理对象

        //构造器
        CameraRemoteProxy(IRemoteObject cameraRemote) {
            this.cameraRemote = cameraRemote;
        }

        @Override
        public IRemoteObject asObject() {
            return cameraRemote;
        }

        //远程控制（远程拍摄，远程切换相机朝向，开启推流，停止推流）
        private void remoteControl(int requestType) throws RemoteException {
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
            try {
                cameraRemote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    HiLog.error(LOG_LABEL, "RemoteException:");
                }

            } catch (RemoteException e) {
                HiLog.error(LOG_LABEL, "RemoteException:");
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }

        //改变远程相机模式
        private void changeRemoteCameraMode(int requestType,int cameraModeId) throws RemoteException {
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
            data.writeInt(cameraModeId);
            try {
                cameraRemote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    HiLog.error(LOG_LABEL, "RemoteException:");
                }

            } catch (RemoteException e) {
                HiLog.error(LOG_LABEL, "RemoteException:");
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }

        //远程发送已编码数据给本机
        private void sendEncodedData(int requestType,byte[] buffers,String fromDeviceId) throws RemoteException {
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
//            int capacity = buffers.length;
            data.setCapacity(512000);
            data.writeByteArray(buffers);
            data.writeString(fromDeviceId);
            try {
                cameraRemote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    HiLog.error(LOG_LABEL, "RemoteException:");
                }

            } catch (RemoteException e) {
                HiLog.error(LOG_LABEL, "RemoteException:");
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //③初始化互动组件
    private void initComponent() {
        cameraView = findComponentById(ResourceTable.Id_cameraView);
        cameraController = cameraView.getCameraController();
        cameraController.setOutsideCameraCallBack(this);
        cameraController.setIsMaster(isMaster);


        //定义格式
        fmt = new Format();
        fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
        // yuv数据解码视频旋转了90度，解码宽高对换
        fmt.putIntValue(Format.WIDTH, 720);
        fmt.putIntValue(Format.HEIGHT, 1440);
        fmt.putIntValue(Format.BIT_RATE, 10000000);
        fmt.putIntValue(Format.COLOR_MODEL, CodecConst.CODEC_COLOR_MODEL);
        fmt.putIntValue(Format.FRAME_RATE, 30);
        fmt.putIntValue(Format.FRAME_INTERVAL, CodecConst.CODEC_FRAME_INTERVAL);
        fmt.putIntValue(Format.BITRATE_MODE, CodecConst.CODEC_BITRATE_MODE);

        //如果是主机，则根据从机数量初始化解码器
        if (isDistributed && isMaster) {
            //根据从机数量创建推流窗口对象
            switch (slaveNum) {
                case 2:
                    pushFlowView2 = findComponentById(ResourceTable.Id_pushFlowView2);
                    pushFlowView2.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
                        @Override
                        public void surfaceCreated(SurfaceOps surfaceOps) {
                            pushFlowSurface2 = surfaceOps.getSurface();
                            videoDecoder2 = new CodecDecoder.Builder().setFormat(fmt).setSurface(pushFlowSurface2).create();
                            videoDecoder2.openDecoder();//开启解码器2
                        }

                        @Override
                        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

                        }

                        @Override
                        public void surfaceDestroyed(SurfaceOps surfaceOps) {

                        }
                    });
                    break;
                //穿透
                case 1:
                    pushFlowView1 = findComponentById(ResourceTable.Id_pushFlowView1);
                    pushFlowView1.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
                        @Override
                        public void surfaceCreated(SurfaceOps surfaceOps) {
                            pushFlowSurface1 = surfaceOps.getSurface();
                            videoDecoder1 = new CodecDecoder.Builder().setFormat(fmt).setSurface(pushFlowSurface1).create();
                            videoDecoder1.openDecoder();//开启解码器1

                        }

                        @Override
                        public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {

                        }

                        @Override
                        public void surfaceDestroyed(SurfaceOps surfaceOps) {

                        }
                    });
                    break;
            }
        }


        //获取按钮实例
        radioContainer = findComponentById(ResourceTable.Id_radio_container);
        btnAction = findComponentById(ResourceTable.Id_camera_btn_action);
        btnThumbnail = findComponentById(ResourceTable.Id_camera_btn_thumbnail);
        btnSwitch = findComponentById(ResourceTable.Id_camera_btn_switch);
        btnFlash = findComponentById(ResourceTable.Id_camera_btn_flash);
        btnAsr = findComponentById(ResourceTable.Id_camera_btn_asr);
        btnSplit = findComponentById(ResourceTable.Id_camera_btn_split);
        btnSearch = findComponentById(ResourceTable.Id_camera_btn_search);
        radioContainer.setMarkChangedListener(this);
        btnAction.setTouchEventListener(this);
        btnThumbnail.setClickedListener(this);
        btnSwitch.setClickedListener(this);
        btnFlash.setClickedListener(this);
        btnAsr.setClickedListener(this);
        btnSplit.setClickedListener(this);
        btnSearch.setClickedListener(this);
        if (isDistributed) deviceTypeText.setClickedListener(component -> connectService());

//        checkCurrentCameraMode();//检查当前相机模式

        HiLog.info(LOG_LABEL, "initComponent()-完成");
    }
//-------------------------------------------------------------------------------------------------------------

    //检查当前相机模式
    @Deprecated
    private void checkCurrentCameraMode() {
        int currentCheckedIndex = radioContainer.getMarkedButtonId();
        //如果当前选中拍照
        if (radioContainer.getComponentAt(currentCheckedIndex).getId() == ResourceTable.Id_radio_button_photo) {
            cameraController.setCameraMode(PHOTO_MODE);
            HiLog.info(LOG_LABEL, "checkCurrentMode()-当前模式为拍照");
        }
        //如果当前选中录像
        else if (radioContainer.getComponentAt(currentCheckedIndex).getId() == ResourceTable.Id_radio_button_record) {
            cameraController.setCameraMode(RECORD_MODE);
            HiLog.info(LOG_LABEL, "checkCurrentMode()-当前模式为录像");
        }
    }
//=============================================================================================================








//***********************************************触摸事件（核心功能）***********************************************

    //“拍摄按钮”点击事件（暂时：向下兼容api）
    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        int action = touchEvent.getAction();
        CameraMode cameraMode = cameraController.getCameraMode();
        if (component != btnAction) return false;
//-------------------------------------------------------------------------------------------------------------

        //按下
        if (action == TouchEvent.PRIMARY_POINT_DOWN) {
            boolean isRecording = cameraController.isRecording();

            //照片模式按下设置图标为“照片按下”
            if (cameraMode == PHOTO_MODE) {
                btnAction.setPixelMap(ResourceTable.Media_camera_btn_photo_pressed);
                ToastUtil.showToast(this, "拍照完成");
            }
            //录像模式未录像，按下设置图标为“录像中”
            else if (cameraMode == RECORD_MODE && !isRecording) {
                btnAction.setPixelMap(ResourceTable.Media_camera_btn_recording);
                ToastUtil.showToast(this, "开始录像");
            }
            //录像模式正在录像，按下设置图标为“未录像”
            else if (cameraMode == RECORD_MODE && isRecording) {
                btnAction.setPixelMap(ResourceTable.Media_camera_btn_record);
                ToastUtil.showToast(this, "停止录像");
            }

            //如果是多机位模式且为主机端，则向从机广播公共事件（远程同步拍摄）
            if (isDistributed && isMaster) {
                if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                    try {
                        for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                            cameraRemoteProxy.remoteControl(RemoteCommand.REMOTE_ACTION.requestCode());
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            cameraAction();//执行相机活动
        }
//-------------------------------------------------------------------------------------------------------------

        //抬起
        else if (action == TouchEvent.PRIMARY_POINT_UP) {
            if (cameraMode == PHOTO_MODE) {//照片模式抬起设置图标为“照片抬起”
                btnAction.setPixelMap(ResourceTable.Media_camera_btn_photo);
            }
        }
        HiLog.info(LOG_LABEL, "点击了相机活动按钮");

        return true;
    }
//*************************************************************************************************************




//***********************************************单击事件（辅助功能）***********************************************

    //单击事件
    @Override
    public void onClick(Component component) {

        //点击“缩略图”
        if (component == btnThumbnail) {
            //跳转到相册
            Intent intent = new Intent();
            Operation operation = new Intent.OperationBuilder()
                    .withAction("android.intent.action.PICK")
                    .withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)
                    .build();
            intent.setUriAndType(null, "image/*");
            intent.setOperation(operation);
            startAbility(intent);
            HiLog.info(LOG_LABEL, "点击了缩略图按钮，进入相册");
        }
//-------------------------------------------------------------------------------------------------------------

        //点击“切换相机”
        else if (component == btnSwitch) {
            cameraController.switchCamera();

            //如果是多机位模式且为主机端，广播公共事件（同步切换相机朝向）
            if (isDistributed && isMaster) {
                if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                    try {
                        for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                            cameraRemoteProxy.remoteControl(RemoteCommand.CHANGE_CAMERA_TYPE.requestCode());
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            if (cameraController.isFrontCamera()) {
                ToastUtil.showToast(this, "当前为前置摄像头");
                HiLog.info(LOG_LABEL, "当前为前置摄像头");
            } else {
                ToastUtil.showToast(this, "当前为后置摄像头");
                HiLog.info(LOG_LABEL, "当前为后置摄像头");
            }
        }
//-------------------------------------------------------------------------------------------------------------

        //点击“闪光灯”
        else if (component == btnFlash) {
            int flashMode = cameraController.getFlashMode();
            switch (flashMode) {
                case (Metadata.FlashMode.FLASH_CLOSE)://1：关闭
                    flashMode++;
                    btnFlash.setPixelMap(ResourceTable.Media_flash_on);
                    HiLog.info(LOG_LABEL, "闪光灯开");
                    break;
                case (Metadata.FlashMode.FLASH_OPEN)://2：打开
                    flashMode++;
                    btnFlash.setPixelMap(ResourceTable.Media_flash_alwayson);
                    HiLog.info(LOG_LABEL, "闪光灯常亮");
                    break;
                case (Metadata.FlashMode.FLASH_ALWAYS_OPEN)://3：常亮
                    flashMode = 0;
                    btnFlash.setPixelMap(ResourceTable.Media_flash_auto);
                    HiLog.info(LOG_LABEL, "闪光灯自动");
                    break;
                case (Metadata.FlashMode.FLASH_AUTO)://0：自动
                    flashMode++;
                    btnFlash.setPixelMap(ResourceTable.Media_flash_off);
                    HiLog.info(LOG_LABEL, "闪光灯关");
                    break;
            }

            cameraController.setFlashMode(flashMode);
            cameraController.previewFrameConfig();//预览帧配置
            cameraController.photoFrameConfig();//拍照帧配置
        }
//-------------------------------------------------------------------------------------------------------------

        //点击“语音控制”
        else if (component == btnAsr) {
            if (!isAsrOn) {
                btnAsr.setPixelMap(ResourceTable.Media_asr_on);
                isAsrOn = true;

                //初始化音频捕获器和ASR客户端
                initAudioCapturer();
                initAsrClient();

                HiLog.info(LOG_LABEL, "语音控制开");
            } else if (isAsrOn) {
                btnAsr.setPixelMap(ResourceTable.Media_asr_off);
                isAsrOn = false;

                //停止ASR
                stopAsr();

                HiLog.info(LOG_LABEL, "语音控制关");
            }
        }
//-------------------------------------------------------------------------------------------------------------

        //点击“分屏预览”
        else if (component == btnSplit) {
            if (!isDistributed || !isMaster){
                ToastUtil.showToast(this,"仅多机位模式主机可用");
                return;
            }

            DirectionalLayout pushFlowLayout = findComponentById(ResourceTable.Id_pushFlow_layout);//承载两个推流窗口的布局对象

            //一台从机时的布局配置（高度权重3）3：3
            DirectionalLayout.LayoutConfig OneSlaveLayoutConfig = new DirectionalLayout
                    .LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, 0);
            OneSlaveLayoutConfig.weight=3;
            //两台从机时的布局配置（高度权重2）3：2
            DirectionalLayout.LayoutConfig TwoSlaveLayoutConfig = new DirectionalLayout
                    .LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, 0);
            TwoSlaveLayoutConfig.weight=2;

            //两台从机时的SurfaceProvider布局配置（横向）（宽度权重1）1：1
            DirectionalLayout.LayoutConfig TwoSlaveViewConfig = new DirectionalLayout
                    .LayoutConfig(0, ComponentContainer.LayoutConfig.MATCH_PARENT);
            TwoSlaveViewConfig.weight=1;

            //恢复窗口布局配置
            DirectionalLayout.LayoutConfig closeLayoutConfig = new DirectionalLayout.LayoutConfig(0, 0);

            //开启分屏
            if (!isSplitOn) {
                if (cameraController.isRecording()){
                    ToastUtil.showToast(this,"请在录像前开启");
                    return;
                }

                btnSplit.setPixelMap(ResourceTable.Media_screen_normal);
                isSplitOn = true;
                cameraController.setIsPushFlowOn(true);

                //如果是多机位模式且为主机端，广播公共事件（启动从机推流）
                if (isDistributed && isMaster) {
                    if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                        try {
                            for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                                cameraRemoteProxy.remoteControl(RemoteCommand.START_PUSHFLOW.requestCode());
                            }
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }

                //双机位
                if (slaveNum == 1){
                    //预览窗口分屏
                    pushFlowLayout.setLayoutConfig(OneSlaveLayoutConfig);
                }
                //三机位
                else if (slaveNum ==2){
                    //预览窗口分屏
                    pushFlowLayout.setLayoutConfig(TwoSlaveLayoutConfig);
                    pushFlowView1.setLayoutConfig(TwoSlaveViewConfig);
                    pushFlowView2.setLayoutConfig(TwoSlaveViewConfig);
                }

                HiLog.info(LOG_LABEL, "分屏预览开");
            }

            //关闭分屏
            else {
                if (cameraController.isRecording()){
                    ToastUtil.showToast(this,"请先停止录像");
                    return;
                }

                btnSplit.setPixelMap(ResourceTable.Media_screen_split);
                isSplitOn = false;
                cameraController.setIsPushFlowOn(false);

                //恢复预览窗口
                pushFlowLayout.setLayoutConfig(closeLayoutConfig);


//                //关闭所有解码器
//                switch (slaveNum) {
//                    case 1:
//                        videoDecoder1.stopDecode();//关闭解码器1
//                        break;
//                    case 2:
//                        videoDecoder1.stopDecode();//关闭解码器1
//                        videoDecoder2.stopDecode();//关闭解码器2
//                        break;
//                }

                //如果是多机位模式且为主机端，广播公共事件（停止从机推流）
                if (isDistributed && isMaster) {
                    if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                        try {
                            for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                                cameraRemoteProxy.remoteControl(RemoteCommand.STOP_PUSHFLOW.requestCode());
                            }
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }

                HiLog.info(LOG_LABEL, "分屏预览关");
            }
            cameraController.photoCameraConfig();//进行拍照专用相机配置-随后进入预览帧配置（刷新主机相机配置）
        }
//-------------------------------------------------------------------------------------------------------------

        //点击“跨设备搜索”
        else if (component == btnSearch) {

                Operation operationSearch = new Intent.OperationBuilder()
                        .withDeviceId("")
                        .withBundleName(getBundleName())
                        .withAbilityName(DistributedSearchAbility.class.getName())
                        .build();
                Intent intentSearch = new Intent();
                intentSearch.setOperation(operationSearch);
                startAbility(intentSearch);


                HiLog.info(LOG_LABEL, "打开跨设备搜索");

        }
    }
//*************************************************************************************************************




//**************************************************相机功能行为**************************************************

    //相机功能行为（启动拍照/录像）
    private void cameraAction() {
        Camera cameraDevice = cameraController.getCameraDevice();
        boolean isRecording = cameraController.isRecording();
        CameraMode cameraMode = cameraController.getCameraMode();
        if (cameraDevice == null) {
            return;
        }
//-------------------------------------------------------------------------------------------------------------

        //如果当前相机是拍照模式
        if (cameraMode == PHOTO_MODE) {
            if (photoFrameConfig == null) {
                photoFrameConfig = cameraController.photoFrameConfig();//复用生成的拍照帧配置
            }
            cameraDevice.triggerSingleCapture(photoFrameConfig);//启动相机单帧捕获（拍照）
            HiLog.info(LOG_LABEL, "○启动拍照单帧捕获");
        }
//-------------------------------------------------------------------------------------------------------------

        //如果当前相机是录像模式
        else if (cameraMode == RECORD_MODE) {
            //如果当前为非录像状态，则启动录像
            if (!isRecording) {
                cameraController.setIsRecording(true);
                cameraController.initMediaRecorder();//初始化录像属性
                cameraController.videoCameraConfig();//进行录像专用相机配置（+预览画布 +录像画布）
                //随后进入onConfigured()进行录像帧配置（+预览画布 +录像画布）
                //录像帧配置完成后直接开始录制
            }

            //如果当前为录像状态，则停止录像
            else if (isRecording) {
                cameraController.setIsRecording(false);
                cameraController.stopRecord();//停止录像（+预览画布 ×停止循环帧捕获（录像））

                HiLog.info(LOG_LABEL, "当前是录像模式且正在录像，停止录像");
            }
        }

    }

//*************************************************************************************************************




//****************************************************模式切换****************************************************

    //（单选框）拍照-录像模式变化
    @Override
    public void onCheckedChanged(RadioContainer radioContainer, int i) {
        if (radioContainer == null) return;
        boolean isRecording = cameraController.isRecording();

        //切换到拍照模式
        if (radioContainer.getComponentAt(i).getId() == ResourceTable.Id_radio_button_photo) {

            if (isRecording) {
                ToastUtil.showToast(this, "请先停止录像");
                return;
            }

            btnAction.setPixelMap(ResourceTable.Media_camera_btn_photo);
            cameraController.setCameraMode(PHOTO_MODE);
            cameraController.photoCameraConfig();//进行拍照专用相机配置（+预览画布 +图片接收器）
            ToastUtil.showToast(this, "拍照模式");
            HiLog.info(LOG_LABEL, "onCheckedChanged()-当前模式为拍照");

            //如果是多机位模式且为主机端，则广播公共事件（将从机设置为拍照模式）
            if (isDistributed && isMaster) {
                if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                    try {
                        for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                            cameraRemoteProxy.changeRemoteCameraMode(
                                    RemoteCommand.CHANGE_CAMERA_MODE.requestCode(),
                                    PHOTO_MODE.getCameraModeId());
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
//-------------------------------------------------------------------------------------------------------------

        //切换到录像模式
        else if (radioContainer.getComponentAt(i).getId() == ResourceTable.Id_radio_button_record) {
            btnAction.setPixelMap(ResourceTable.Media_camera_btn_record);
            cameraController.setCameraMode(RECORD_MODE);
            ToastUtil.showToast(this, "录像模式");
            HiLog.info(LOG_LABEL, "onCheckedChanged()-当前模式为录像");
            //此时相机配置仍为拍照相机配置（+预览画布 +图片接收器）

            //如果是多机位模式且为主机端，则广播公共事件（将从机设置为录像模式）
            if (isDistributed && isMaster) {
                if (cameraRemoteProxys != null && !cameraRemoteProxys.isEmpty()) {
                    try {
                        for (CameraRemoteProxy cameraRemoteProxy : cameraRemoteProxys) {
                            cameraRemoteProxy.changeRemoteCameraMode(
                                    RemoteCommand.CHANGE_CAMERA_MODE.requestCode(),
                                    RECORD_MODE.getCameraModeId());
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }
//*************************************************************************************************************




//******************************************OutsideCameraCallBack回调******************************************

    //图片保存时回调
    @Override
    public void onImageSaved(PixelMap pixelMap) {
        //显示缩略图
        getUITaskDispatcher().asyncDispatch(() -> {
            HiLog.info(LOG_LABEL, "显示缩略图");
            ThumbnailDrawTaskUtil drawTask = new ThumbnailDrawTaskUtil(btnThumbnail);
            btnThumbnail.addDrawTask(drawTask);
            drawTask.putPixelMap(pixelMap);
            btnThumbnail.setEnabled(true);
        });

    }

//-------------------------------------------------------------------------------------------------------------

    //相机配置刷新时回调
    @Override
    public void onCameraConfigured(CameraController cameraController) {

        //如果是主机，则根据从机数量初始化解码器
//        if (isDistributed && isMaster && cameraController.getIsPushFlowOn()){
//            switch (slaveNum) {
//                case 1:
//                    videoDecoder1.openDecoder();//开启解码器1
//                    break;
//                case 2:
//                    videoDecoder1.openDecoder();//开启解码器1
//                    videoDecoder2.openDecoder();//开启解码器2
//                    break;
//            }
//
//            HiLog.info(LOG_LABEL, "主机：初始化解码器");
//        }
//        else

        //如果是从机，且目前是推流状态，则初始化编码器
         if (isDistributed && !isMaster && cameraController.getIsPushFlowOn()){
            videoEncoder = new CodecEncoder.Builder().setFormat(fmt).create();
            videoEncoder.setEncodeListener(this);//传出编码后数据的回调
            videoEncoder.openEncoder();//开启编码器
            HiLog.info(LOG_LABEL, "从机：初始化编码器");
        }
    }
//-------------------------------------------------------------------------------------------------------------

    //收到原始推流数据时回调
    @Override
    public void onGetPushFlowOriginalData(byte[] frame) {
        //frame:编码前的原始nv21格式的数据
        //对收到的数据进行编码
        HiLog.info(LOG_LABEL, "从机：编码开始");
        if (videoEncoder.isOpen()) {
            videoEncoder.startEncode(frame);//正式开始编码
        }

    }

//*************************************************************************************************************




//**********************************************CodecListener回调**********************************************

    //收到编码完成的推流数据时回调
    @Override
    public void onGetEncodedBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo) {
        //将编码完成的数据发送给主机端
        if (MasterRemoteProxy != null){
            //从byteBuffer中取出编码完成数据，放入byte数组buffers
            byte[] buffers = new byte[bufferInfo.size];
            byteBuffer.clear();
            byteBuffer.get(buffers);
            //发送buffers给主机端
            try {
                MasterRemoteProxy.sendEncodedData(
                        RemoteCommand.SEND_ENCODED_DATA.requestCode(),
                        buffers,
                        fromDeviceId);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

    }

//************************************************************************************************************




//**************************************************公共事件相关**************************************************

    //CommonEventSubscriber实现类
    public class MyCommonEventSubscriber extends CommonEventSubscriber {
        Context context;

        MyCommonEventSubscriber(CommonEventSubscribeInfo info, Context context) {
            super(info);
            this.context = context;
        }

    //接收公共事件后回调
    @Override
    public void onReceiveEvent(CommonEventData commonEventData) {
        String action = commonEventData.getIntent().getAction();
        RemoteCommand remoteCommand = RemoteCommand.getByAction(action);

        switch (remoteCommand) {
            //远程“相机活动”
            case REMOTE_ACTION:
                CameraMode cameraMode = cameraController.getCameraMode();
                boolean isRecording = cameraController.isRecording();

                //录像模式未录像，按下设置图标为“录像中”
                if (cameraMode == RECORD_MODE && !isRecording) {
                    btnAction.setPixelMap(ResourceTable.Media_camera_btn_recording);
                    ToastUtil.showToast(CameraAbilitySlice.this, "开始录像");
                }
                //录像模式正在录像，按下设置图标为“未录像”
                else if (cameraMode == RECORD_MODE && isRecording) {
                    btnAction.setPixelMap(ResourceTable.Media_camera_btn_record);
                    ToastUtil.showToast(CameraAbilitySlice.this, "停止录像");
                }

                cameraAction();//执行相机活动
                ToastUtil.showToast(context, "远程同步拍摄启动");
                break;
            //远程“切换相机模式”
            case CHANGE_CAMERA_MODE:
                int cameraModeId = commonEventData.getIntent().getIntParam("CHANGED_CAMERA_MODE_ID",0);
                radioContainer.mark(cameraModeId);
                ToastUtil.showToast(context, "相机模式同步切换");
                break;
            //远程“切换相机模式”
            case CHANGE_CAMERA_TYPE:
                btnSwitch.simulateClick();
                ToastUtil.showToast(context, "相机朝向同步切换");
                break;
            //远程设备开启推流
            case START_PUSHFLOW:
                cameraController.setIsPushFlowOn(true);
                cameraController.photoCameraConfig();//进行拍照专用相机配置-随后进入预览帧配置（开始推流）
                ToastUtil.showToast(context, "从机推流开始");
                break;
            //远程设备停止推流
            case STOP_PUSHFLOW:
                cameraController.setIsPushFlowOn(false);
                cameraController.photoCameraConfig();//进行拍照专用相机配置-随后进入预览帧配置（停止推流）
                videoEncoder.stopEncode();//关闭编码器
                ToastUtil.showToast(context, "从机推流结束");
                break;
            //从机发送编码完成的数据给主机
            case SEND_ENCODED_DATA:
                //收到来自从机的编码完成数据，解码，将图像显示在对应的窗口上
                Intent dataIntent = commonEventData.getIntent();
                byte[] buffers = dataIntent.getByteArrayParam("ENCODED_DATA");
                String fromDeviceId = dataIntent.getStringParam("FROM_DEVICE_ID");
                HiLog.info(LOG_LABEL, "接收编码数据完成√。");
                System.out.println("接收编码数据完成√。");
                switch (slaveNum) {
                    case 1:
                        videoDecoder1.startDecode(buffers);
                        System.out.println("videoDecoder1.startDecode(buffers)...");
                        break;
                    case 2:
                        if (fromDeviceId.equals(slaveDeviceIds.get(0))) {
                            videoDecoder1.startDecode(buffers);
                            System.out.println("videoDecoder1.startDecode(buffers)...");
                            break;
                        } else if (fromDeviceId.equals(slaveDeviceIds.get(1))) {
                            videoDecoder2.startDecode(buffers);
                            System.out.println("videoDecoder2.startDecode(buffers)...");
                            break;
                        }
                }
        }

        HiLog.info(LOG_LABEL, "接收远程公共事件成功√。");
    }
}
//-------------------------------------------------------------------------------------------------------------

    //①订阅远程事件
    //从机订阅
    public void subscribeRemoteEvent(Context context) {
        //创建matchingSkills添加要订阅的事件
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(RemoteCommand.REMOTE_ACTION.action());
        matchingSkills.addEvent(RemoteCommand.CHANGE_CAMERA_MODE.action());
        matchingSkills.addEvent(RemoteCommand.CHANGE_CAMERA_TYPE.action());
        matchingSkills.addEvent(RemoteCommand.START_PUSHFLOW.action());
        matchingSkills.addEvent(RemoteCommand.STOP_PUSHFLOW.action());
        //把matchingSkills封装到subscribeInfo中
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        //把subscribeInfo封装到subscriber中
        subscriber = new MyCommonEventSubscriber(subscribeInfo, context);
        //订阅subscriber
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
            HiLog.info(LOG_LABEL, "订阅远程公共事件成功√。");
        } catch (RemoteException e) {
            HiLog.error(LOG_LABEL, "订阅远程公共事件失败。");
        }

    }

    //主机订阅
    public void subscribeMasterEvent(Context context) {
        //创建matchingSkills添加要订阅的事件
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(RemoteCommand.SEND_ENCODED_DATA.action());
        //把matchingSkills封装到subscribeInfo中
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        //把subscribeInfo封装到subscriber中
        subscriber = new MyCommonEventSubscriber(subscribeInfo, context);
        //订阅subscriber
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
            HiLog.info(LOG_LABEL, "订阅远程公共事件成功√。");
        } catch (RemoteException e) {
            HiLog.error(LOG_LABEL, "订阅远程公共事件失败。");
        }

    }
//-------------------------------------------------------------------------------------------------------------

    //②取消订阅远程事件
    public void unSubscribe(MyCommonEventSubscriber subscriber) {
        try {
            CommonEventManager.unsubscribeCommonEvent(subscriber);
            HiLog.info(LOG_LABEL, "取消订阅远程公共事件成功√。");
        } catch (RemoteException e) {
            HiLog.error(LOG_LABEL, "订取消阅远程公共事件失败。");
        }
    }
//*************************************************************************************************************




//***************************************************语音识别****************************************************

    private void initAsrClient() {
        asrClient = AsrClient.createAsrClient(this).orElse(null);
        getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(new Runnable() {
            @Override
            public void run() {
                initListener();
            }
        });
    }

    private AsrIntent setInitIntent() {
        AsrIntent initIntent = new AsrIntent();
        initIntent.setAudioSourceType(AsrIntent.AsrAudioSrcType.ASR_SRC_TYPE_PCM);
        initIntent.setEngineType(AsrIntent.AsrEngineType.ASR_ENGINE_TYPE_LOCAL);
        return initIntent;
    }

    private AsrIntent setStartIntent() {
        AsrIntent asrIntent = new AsrIntent();
        asrIntent.setVadEndWaitMs(2000);
        asrIntent.setVadFrontWaitMs(4800);
        asrIntent.setTimeoutThresholdMs(20000);
        return asrIntent;
    }

    private void openAudio() {
        System.out.println("打开音频");
        System.out.println("openAudio");
        if (!isAsrRecord) {
            asrClient.startListening(setStartIntent());
            isAsrRecord = true;
            poolExecutor.submit(new AudioCaptureRunnable());
        }
    }

    /**
     * Obtains PCM audio streams and sends them to the ASR engine during recording.
     */
    private class AudioCaptureRunnable implements Runnable {
        @Override
        public void run() {
            byte[] buffers = new byte[1280];
            audioCapturer.start();
            while (isAsrRecord) {
                int ret = audioCapturer.read(buffers, 0, 1280);
                if (ret <= 0) {
                    System.out.println("======Error read data");
                } else {
                    asrClient.writePcm(buffers, 1280);
                }
            }
        }
    }

    private void recognizeWords(String result) {
        ZSONObject zsonObject = ZSONObject.stringToZSON(result);
        ZSONObject zsonObj = new ZSONObject();
        if (zsonObject.getZSONArray("result").get(0) instanceof ZSONObject) {
            zsonObj = (ZSONObject) zsonObject.getZSONArray("result").get(0);
        }
        String resultWord = zsonObj.getString("ori_word").replace(" ", "");
        boolean command = COMMAND_MAP.getOrDefault(resultWord, false);
        System.out.println("===resultWord===" + resultWord + "===" + command);
        if (command && !recognizeOver) {
            recognizeOver = true;
            System.out.println("执行命令.....");
            asrHandler.sendEvent(0);
            asrClient.stopListening();
        }
    }

    private void initListener() {
        // Initializes asr.
        if (asrClient != null) {
            asrClient.init(setInitIntent(), new AsrListener() {
                @Override
                public void onInit(PacMap params) {
                    System.out.println("======onInit======");
                    openAudio();
                }

                @Override
                public void onError(int error) {
                    System.out.println("======error:" + error);
                }

                @Override
                public void onIntermediateResults(PacMap pacMap) {
                    String result = pacMap.getString(AsrResultKey.RESULTS_INTERMEDIATE);
                    System.out.println("======onIntermediateResults,result:" + result);
                    recognizeWords(result);
                }

                @Override
                public void onResults(PacMap results) {
                    System.out.println("======onResults:"+results);
                    recognizeOver = false;
                    asrClient.startListening(setStartIntent());
                }

                @Override
                public void onEnd() {
                    System.out.println("======onEnd:");
                    recognizeOver = false;
                    asrClient.stopListening();
                    asrClient.startListening(setStartIntent());
                }

                @Override
                public void onEvent(int i, PacMap pacMap) {

                }

                @Override
                public void onAudioStart() {

                }

                @Override
                public void onAudioEnd() {

                }

                @Override
                public void onBeginningOfSpeech() {

                }

                @Override
                public void onRmsChanged(float v) {

                }

                @Override
                public void onBufferReceived(byte[] bytes) {

                }

                @Override
                public void onEndOfSpeech() {

                }
            });
        }
    }

    private void initAudioCapturer() {
        poolExecutor =
                new ThreadPoolExecutor(
                        3,
                        3,
                        6,
                        TimeUnit.SECONDS,
                        new LinkedBlockingQueue<>(6),
                        new ThreadPoolExecutor.DiscardOldestPolicy());

        AudioStreamInfo audioStreamInfo =
                new AudioStreamInfo.Builder()
                        .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)
                        .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO)
                        .sampleRate(16000)
                        .build();

        AudioCapturerInfo audioCapturerInfo = new AudioCapturerInfo.Builder().audioStreamInfo(audioStreamInfo).build();

        audioCapturer = new AudioCapturer(audioCapturerInfo);
    }

    private void stopAsr(){
        isAsrRecord = false;
        recognizeOver = false;
        asrClient.stopListening();
        asrClient.destroy();
        audioCapturer.stop();
    }
//*************************************************************************************************************




//************************************************其他生命周期回调*************************************************

    //激活
    @Override
    public void onActive() {
        super.onActive();

        HiLog.info(LOG_LABEL, "生命周期-onActive()");
    }

    //回到前台
    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);

        HiLog.info(LOG_LABEL, "生命周期-onForeground()");
    }

    //停止
    @Override
    protected void onStop() {
        super.onStop();
        cameraController.releaseCamera();
        if (isDistributed && !isMaster) {
            unSubscribe(subscriber);
        }
        HiLog.info(LOG_LABEL, "生命周期-onStop()");
    }
}


